#pragma once
#include"global.h"
#include"function.h"
#include<array>
#include<string>
#include<memory>
using namespace std;
class V9C
{
private:
	const static array<array<string,3>,3> _NineStr;
	static int _Symbol(const string& data,int first,int last);
	static string _NineCode(const string& data,uint32_t pos,uint32_t k);
	//_Str:object , k:length of every 9code , data/fist/last original string
	static void _Code(string& _Str,uint32_t k,const string& data,uint32_t first,uint32_t last);
public:
	V9C(void);
	~V9C(void);
	static unique_ptr<string> code(const string& data,uint32_t K=8);
	static unique_ptr<string> vcode(const string& data,uint32_t L=240);
};

//recongnise 0(0),1(1),U(2),X(3)
inline int V9C::_Symbol(const string& data,int first,int last)
{
	bool zero=false;
	bool one=false;
	if(first>=last)
		throw msg("V9C::_Symbol parameter invalid");
	for(;first!=last;first++)
	{
		if(data.at(first)=='0')
			zero=true;
		else if(data.at(first)=='1')
			one=true;
	}
	if(zero&&one)
		return 2;//'U';
	else if(zero)
		return 0;//'0';
	else if(one)
		return 1;//'1';
	else
		return 3;//'X';
}
//k= K/2
inline string V9C::_NineCode(const string& data,uint32_t pos,uint32_t k)
{	
	//normal
	int x=_Symbol(data,pos,pos+k);
	int y=_Symbol(data,pos+k,pos+(k<<1));
	if(x==3&&y==3)
	{
		x=0; 
		y=0;
	}
	else if(x==3)
	{
		if(y==0)x=0;
		else if(y==1)x=1;
		else x=0;
	}
	else if(y==3)
	{
		if(x==0)y=0; 
		else if(x==1)y=1;
		else y=0;
	}
	string ninecode=_NineStr.at(x).at(y);
	if(x==2)//U
		ninecode.append(data,pos,k);
	if(y==2)
		ninecode.append(data,pos+k,k);
	return ninecode;
}
